package org.languageguide.readings;

/*
 * Wraps each word of a text with span tags   
 * 
 *   	<span id="w0" class="w">I</span> <span id="w1" class="w">am</span>
 *   
 *  The ids consist of 'w' and the index of that word in the document.
 *  
 *  'Special Characters' like ', and ", are not considered part of a word.
 *  
 * 
 */

public class StandardWordWrapper implements WordWrapper{

	private int location = 0;
	private int beginTagLocation;
	private StringBuilder readingBuilder;
	private String idPrefix = "w";
	private String word = "";
	private int wordStart = 0;
	private int wordCounter = 0;
	private String text;
	//private boolean abreviationEncountered = false;
	private final String spanEnd = "</span>";
	
	public String wrap(String textToProcess) {
		
		readingBuilder = new StringBuilder(textToProcess);
		
		boolean startSpecialCharacter = false;
		
		/*
		 * Find the start and end of words, then wrap those words with span tags
		 */
		while (hasMore(location)){
			char i = readingBuilder.charAt(location);
			if (i == '<'){
				if (word.length() > 0){
					String tag = advanceToTagEndAndReturnContents();
					if (tag.startsWith("/span")){ // this enables you to handle cases like l'<span class="linked>usine</span>
						processWord(wordStart, location + 1);
						wordStart = location + 1;
					}
					else if (!tag.startsWith("span") || tag.startsWith("span class=\"translation\"")){ // this enables you to handle cases like l'<span class="linked>usine</span> 
						processWord(wordStart, beginTagLocation);
						wordStart = location + 1;
					}
				}
				else{
					advanceToTagEnd();
					wordStart = location + 1;
				}
			}
			else if (i == ' '){
				if (word.length() > 0){
					processWord(wordStart, location);
				}
				else{
					wordStart = location + 1;
				}
			}
			else if (i == '&'){
				// '&' indicates the start of an html character 
				startSpecialCharacter = true;
				word += i;
			}
			else if (i == ';'){ 
				/* check and see if the ';' is marking the end of an html character
				 * or is punctuatation */
				if (startSpecialCharacter){
					word += i;
					startSpecialCharacter = false;
				}
				else{ // treat as punctuation
					processWord(wordStart, location);
				}	
			}
			/* 
			 * if it's a '.' and not part of an abbreviation or number, 
			 * process the word as if it was punctuation
			 */
			else if (i == '.' && notPartOfAbreviationOrNumber()){
				/* 
				 * When we encounter abreviations like 'P.S.' abreviationEncountered is set to true 
				 */
				//if (!abreviationEncountered){
				processWord(wordStart, location);
				//}
				//else {
					//word += i;
				//}
			}
			else if (WrapperHelper.isPunctuationOtherThanPeriod(i)){
				processWord(wordStart, location);
			}
			else{
				word += i;
			}
			location++;
		}
		if (!word.equals("")){
			processWord(wordStart, location);
		}
		
		text = readingBuilder.toString();
		return text;
	}
	
	private boolean shouldWordBeProcessed(){
		if (word.equals("\"") || word.equals("\'") || word.equals("-") || word.equals(":")){
			return false;
		}
		else{
			return true;
		}
	}
	
	private boolean notPartOfAbreviationOrNumber(){
		char characterAfterPunctuation = readingBuilder.charAt(location + 1);
		String possibleAbbreviation = word + ".";
		if (possibleAbbreviation.equals("etc.")){
			return false;
		}
		else if (possibleAbbreviation.equals("P.S.")){
			return false;
		}
		
		if (characterAfterPunctuation == ' ' || characterAfterPunctuation == '<'){
			return true;
		}
		//abreviationEncountered = true;
		return false;
	}
	

	public String getText(){
		return text;
	}
	
	public int getWordCount(){
		return wordCounter;
	}
	
	private void processWord(int start, int end){
		word = word.trim();
		if (!shouldWordBeProcessed()){
			word = "";
			return;
		}
		if (word.equals("")){ // this should be prevented
			return;
		}
		String spanStart = "<span class=\"w\" id=\"" + idPrefix + wordCounter++ + "\">";
		readingBuilder.insert(end, spanEnd);
		readingBuilder.insert(start, spanStart);
		location += spanStart.length() + spanEnd.length();
		wordStart = location + 1; 
		word = "";
		//if (abreviationEncountered)
			//abreviationEncountered = false;
	}
	
	private boolean hasMore(int location){
		if (location < readingBuilder.length())
			return true;
		else return false;
	}
	
	private void advanceToTagEnd(){
		location++;
		char cha = readingBuilder.charAt(location);
		//StringBuilder tag = new StringBuilder(""); 
		
		while (cha != '>'){
			//tag.append(cha);
			//System.out.println(tag);
			location++;	
			cha = readingBuilder.charAt(location);
		}
		
	}
	
	private String advanceToTagEndAndReturnContents(){
		beginTagLocation = location; 
		location++;
		char cha = readingBuilder.charAt(location);
		StringBuilder tag = new StringBuilder(""); 
		
		while (cha != '>'){
			tag.append(cha);
			//System.out.println(tag);
			location++;	
			cha = readingBuilder.charAt(location);
		}
		return tag.toString();
	}
	
	public static void main(String[] args) {
		//String paragraph = "<p>U.S. Ch&egrave;re Maman, cher Papa;</p><p>Me voil&agrave; install&eacute;e &agrave; Montpellier! J'habite avec une famille tr&egrave;s gentille: Jacques et Marie Trapet et leurs enfants, Cecile et Juliette. Je trouve leur maison tr&egrave;s belle, mais ils ne sont pas contents et ils cherchent une autre maison &agrave; la campagne, avec des chambres individuelles pour les enfants. Nous sommes tr&egrave;s occup&eacute;s ici.</p>";
		//String paragraph = "<p>Le Voyage du Horla</p><p><span id=\"s0\">J'avais reçu, <p>l'<span class=\"linked\">usine</span> Making money is never easy but on the South Pacific island of Yap it used to be very dangerous, difficult work!</p> " +
				//"<p>Although the Yapese people usually spend dollars, their traditional money, the Rai, is actually made of stone. Measuring up to 3.6 metres in diameter, and weighing up to 4 tonnes, this disk-shaped \"stone money\" is still used for weddings and the sale of land.</p>";
		String paragraph = "<p>Le Voyage du Horla</p>" + 
"<p>J'avais reçu, dans la matinée du 8 juillet, le télégramme que voici: 'Beau temps. Toujours mes prédictions. Frontières belges. Départ du matériel et du personnel à midi, au siège social. Commencement des manoeuvres à trois heures. Ainsi donc je vous attends à l'usine à partir de cinq heures. JOVIS.</p>" +
"<p>'A cinq heures précises, j'entrais à l'usine à gaz de La Villette. On dirait les ruines colossales d'une ville de cyclopes. D'énormes et sombres avenues s'ouvrent entre les lourds gazomètres alignés l'un derrière l'autre, pareils à des colonnes monstrueuses, tronquées, inégalement hautes et qui portaient sans doute, autrefois, quelque effrayant édifice de fer.</p>" +
"<p>Dans la cour d'entrée, gît le ballon, une grande galette de toile jaune, aplatie à terre, sous un filet. On appelle cela la mise en épervier; et il a l'air, en effet, d'un vaste poisson pris et mort.</p>" +
"<p>Deux ou trois cents personnes le regardent, assises ou debout, ou bien examinent la nacelle, un joli panier carré, un panier à chair humaine qui porte sur son flanc, en lettres d'or, dans une plaque d'acajou: Le Horla.</p>"; 
		WordWrapper preparer =  new StandardWordWrapper();
		String text = preparer.wrap(paragraph);
		System.out.println(text);
		//preparer.prepare(paragraph, "w");
	}
}
